package cn.shengchao.examstar.ai.application;

import cn.shengchao.examstar.ai.application.command.CreateStudyPlanCommand;
import cn.shengchao.examstar.ai.application.dto.StudyPlanDTO;
import cn.shengchao.examstar.ai.domain.event.StudyPlanCreatedEvent;
import cn.shengchao.examstar.ai.domain.model.StudyPlan;
import cn.shengchao.examstar.ai.domain.repository.IAiStudyPlanRepository;
import cn.shengchao.examstar.ai.domain.service.StudyPlanDomainService;
import cn.shengchao.examstar.ai.domain.valueobject.*;
import cn.shengchao.examstar.shared.domain.event.DomainEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 学习计划应用服务
 * 协调领域服务和基础设施，处理应用层逻辑
 * 负责事务管理和领域事件发布
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StudyPlanApplicationService {
    
    private final IAiStudyPlanRepository studyPlanRepository;
    private final StudyPlanDomainService studyPlanDomainService;
    private final ApplicationEventPublisher eventPublisher;
    
    /**
     * 创建学习计划
     */
    @Transactional
    public StudyPlanDTO createStudyPlan(CreateStudyPlanCommand command) {
        log.info("创建学习计划，用户ID: {}, 类目: {}", command.getUserId(), command.getSpecificationType());
        
        // 转换为值对象
        UserId userId = UserId.of(Long.valueOf(command.getUserId()));
        SpecificationType specificationType = SpecificationType.of(Long.valueOf(command.getSpecificationType()));
        DegreeOfMastery degreeOfMastery = DegreeOfMastery.fromCode(command.getDegreeOfMasteryCode());
        
        // 通过领域服务创建学习计划
        StudyPlan studyPlan = studyPlanDomainService.createStudyPlan(
            specificationType, userId, degreeOfMastery);
        
        // 保存到仓储
        StudyPlan savedStudyPlan = studyPlanRepository.save(studyPlan);
        
        // 发布领域事件
        savedStudyPlan.addDomainEvent(new StudyPlanCreatedEvent(savedStudyPlan.getId(), userId, specificationType));
        publishDomainEvents(savedStudyPlan);
        
        log.info("学习计划创建成功，ID: {}", savedStudyPlan.getId());
        return convertToDTO(savedStudyPlan);
    }

    /**
     * 发布领域事件
     */
    private void publishDomainEvents(StudyPlan studyPlan) {
        List<DomainEvent> events = studyPlan.getDomainEvents();
        for (DomainEvent event : events) {
            eventPublisher.publishEvent(event);
            log.debug("发布领域事件: {}", event.getClass().getSimpleName());
        }
        studyPlan.clearDomainEvents();
    }
    
    /**
     * 转换为DTO
     */
    private StudyPlanDTO convertToDTO(StudyPlan studyPlan) {
        return StudyPlanDTO.builder()
            .id(studyPlan.getId().getValue().toString())
            .userId(studyPlan.getUserId().getValue().toString())
            .specificationType(studyPlan.getSpecificationType().getValue().toString())
            .degreeOfMastery(studyPlan.getDegreeOfMastery().getDescription())
            .degreeOfMasteryCode(studyPlan.getDegreeOfMastery().getCode())
            .dailyStudyDurationMinutes(studyPlan.getDailyStudyDuration().getMinutes().intValue())
            .studyPeriodBeginTime(studyPlan.getStudyPeriod().getStartTime())
            .studyPeriodEndTime(studyPlan.getStudyPeriod().getEndTime())
            .studyAdvice(studyPlan.getStudyAdvice())
            .status(studyPlan.getStatus().getName())
            .statusCode(studyPlan.getStatus().getCode())
            .createTime(studyPlan.getCreateTime())
            .updateTime(studyPlan.getUpdateTime())
            .build();
    }
}